Exploring Oracle Developer/Designer 2000
The Cobb Group This article is reprinted from the August 1996 issue of  Exploring Oracle Developer/2000 and Designer/2000, a monthly publication of The Cobb Group.

Click for a FREE issue!


Debugging your applications, part 1

By Daniel Bill

As much as we hate to admit it, the code we write is not always error free. In fact, one of a programmer's biggest challenges is to identify, locate, and fix code errors as quickly as possible. Oracle has provided some useful features in Developer/2000 to help you with that tedious and often frustrating task of debugging applications--the Debug Messages feature and the full-blown Debugger. Many developers have shied away from using Developer/2000's Debugger tool because of its perceived complexity. We hope we can eliminate some of that confusion and show you how easy it is to use the Debugger to get to the root of your programming errors and determine what's required to fix them.

This article is the first in a two-part series. In this part, we'll look mainly at the Debugger tool and show how you can use it to not only quickly find bugs but also to test possible remedies right at runtime. In the second part in the September issue, we'll address how using Debug Actions can further help you in debugging applications. With that said, let's get started.

Running your application with debug messages

The easiest way to narrow down a program error to a particular trigger is to use Forms 4.5's debug_messages feature. Running an application with debug messages will let you see the name of each PL/SQL trigger in an Alert dialog box, just prior to execution, as shown in Figure A. To run a form with debug messages appearing, enter the following parameters when calling the runtime of your form:

f45run module=myform userid=scott/tiger debug_messages=YES

If your program crashes and you don't know where the problem is, running your application with debug_messages will at least help you find the name of the last trigger you entered before the error occurred. To further narrow down program errors, let's look at Developer/2000's heavy-duty error fixer--the Debugger.

Please note: It can be helpful to use the debug_messages option even if you don't have any errors, just to see the firing sequence of triggers.

Figure A

Running an application with debug_messages lets you see the name of each trigger before it runs.

Debugger basics

Most professional development environments include some type of a debugging tool. Debuggers let you step through your code at runtime and observe what effect your code is having on variables and application items. In general, when running an application with a debugger, you need to be able to indicate where you want to pause execution of your application so that you can start debugging. You can indicate where to have your code pause by defining a breakpoint. Breakpoints are spots in your code where you want program execution to stop temporarily so that you can examine the values of your variables. When a breakpoint is reached in your code, control transfers from your application to the Debugger.

Running your form using the Debugger

To run an application in debug mode, load your form into Designer, select the debug icon from the toolbar <show icon here debugico.pcx>, and then run your form. Please note that you must compile your form with debug mode turned on in order to use the Debugger. This process will create an executable file that also contains references to source code all in the fmx file. When you first run your form in debug mode, you'll see the Debugger window, as shown in Figure B. Select the close icon <closeico.pcx> to close the Debugger window and run your form.

Figure B

When you run a form in debug mode, the Debugger window appears.

The Debugger window is divided into three panes. The top pane is the Source pane, where the source code appears. The middle pane is the Navigator pane, which you use to navigate through your application's various items and variables. The bottom pane is the Interpreter pane, where you can type in debugger statements. We'll look at only the first two panes in this article.

Creating a breakpoint

Breakpoints are the most important thing you need to know about debugging. Let's create one to show how they work. Run your application in debug mode. In the Navigator pane of the Debugger window, click on the plus sign next to the Modules item. From there, drill down until you find a specific trigger in your application where you want code execution to stop. As soon as you select the trigger, the text of the trigger will appear in the Source pane. To have execution stop at a particular line of code, double-click on that line of code in the Source pane to set a breakpoint, as shown in Figure C.

Figure C

By setting a breakpoint in your code, execution will stop at that line of code.

Please note: You must select an executable line of code at which to break. You're not allowed to use comments and statements such as begin. Now click the close icon on the Debugger window, and execution will transfer to your form. When the processing reaches a line of code for which you have a breakpoint set, the processing transfers from your form back to the Debugger and the Debugger window reappears. You can also bring up the Debugger window at any time by selecting the Debug option on the Help menu.

Using the Debugger to find errors

We've shown you how to bring up the Debugger window and how to set breakpoints to stop program execution. Now we'll show you how to use the Debugger to locate problems in your code. The debugging process consists of running your application code in increments and then observing the effect that code has. This lets you identify which line of code is causing an error. But even more than that, you can see the effect of each line of code on local variables, global variables, and even values stored in Forms items. First we'll look at how to incrementally run your code, and then we'll show how to review program data and even change it.

Stepping through your code

When your code comes to a breakpoint, execution of your code is interrupted and the Debugger window takes over. At this point, the Source pane shows you the current trigger or program unit with the current line of code marked with an =>. This is the next line of code to be executed. You have five options for continuing program execution. We describe each of these in Table A.

Table A

step-into
Causes the next line of code to be executed. If a call is being made to another program unit, itwill go into that program unit and pause at the next executable line of code.
step-over
Causes the next line of code to be executed. If a call is being made to another program unit, the Debugger won't step into the program unit but will execute the whole program unit and pause at the next line of code after the call to the subprogram.
step-out
Continues execution until the current subprogram has completed and returned to its calling program.
go
Returns control to your program and closes the Debugger until another a breakpoint is encountered.
reset
Steps out of the Debugger and does not complete execution of the current program unit.

The Debugger provides five options for continuing execution of your code.

What the Stack shows you

You'll notice that the Navigator pane shows the currently executed program unit in an area called the Stack. As your triggers call subprograms and they in turn call other subprograms, the Stack will show you the hierarchy of these programs. Each item under the Stack is called a frame; each frame is numbered starting at 0. Item 0 corresponds to the highest level program unit, the one that initiated the Debugger. Item 1 was called from 0 and item 2 was called from 1, etc. Figure D shows what the Stack looks like. Each item in the Stack contains the program name as well as the number of the next line of code to be executed. The Stack is useful to show you where execution of your code is.

Figure D

The Stack shows you the hierarchy of the programs and subprograms called by your triggers.

Checking values of variables and items

As you step through the lines of code in the debug process, you may come to areas of your code where you think there could be problems. Here you'll want to dig a little deeper and check what's happening with some of your program data. At any point in the debug process, you can take a look at your local variables, global variables, and values of items. Let's see how.

Checking local variables

Local variables are found under the Stack heading, below the corresponding program units. If you look at Figure E, you'll see the local variables for the SET_INI_FILE function as well as any arguments that were passed to it.

Figure E

The SET_INI_FILE function contains these local variables.

Checking global variables

The Navigator pane also contains a heading called Global Variables. Any global variables that may be defined in your form will be listed here, along with their current values.

Checking values of form items

Values of fields that appear on your form are listed under the Modules heading. You'll need to drill down to a specific block to check the current values of items. The drill down process follows this sequence

Modules>formname>Blocks>blockname 

as shown in Figure F.

Figure F

You can check the current values of items by drilling down to a specific block.

Modifying values of variables

You can change the values of local and global variables and form items from the Debugger at any time by simply double-clicking on the value of the item or variable and entering a different value. Changing these values can be quite useful for testing program behavior using different data.

Modifying code at runtime

One of the benefits of the Debugger is that you can make changes to your code at runtime and quickly test those modifications. You can change the code in any program unit or trigger as long as it's not the program unit currently shown in the Source pane. To modify a particular piece of code, you first need to locate the trigger or the program unit in the Navigator. Figure G shows some of the triggers and procedures found in an application. To open up the Editor, simply double-click on the icon next to the trigger or procedure. The code will load into the Editor window, as shown in Figure H. You can now modify the code as you wish, commit it, and exit the Editor window. As you continue running your application, it will use the modified code.

Figure G

Our sample application contains these triggers and procedures.


Figure H

When you double-click on the icon for a trigger or procedure, the code for it will appear in the Editor window.

The modifications you make in the Editor window don't affect your form's fmb file and are also not reflected in the Designer. If you modify your code and want to incorporate that change into your application, you need to go back to the Designer and make the changes there as well. Another approach would be to cut the modified source code from the Debugger and paste it into the appropriate location in the Designer.

Conclusion

Oracle's debugging tools can not only help you quickly track down errors in your code but are also a useful tool to show what's happening as your application executes. Next month, we'll look at another feature of the Debugger, called debug actions.

Daniel Bill is a Project Leader working for the City of Mississauga in Ontario, Canada. He is one of Oracle's Developer/2000 Ambassadors. You can reach him at daniel.bill@city.mississauga.on.ca.

 

[The Cobb Group Home Page]

Copyright (c) 1996 The Cobb Group, a division of Ziff-Davis Publishing Company. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Ziff-Davis Publishing Company is prohibited. The Cobb Group and The Cobb Group logo are trademarks of Ziff-Davis Publishing Company.

Questions? Comments?